/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = wtc_typed_fml32.c                                  */
/*  NOTE      =                                                    */
/*  DATE      = 2015/08/26 by songbb                               */
/*******************************************************************/

#include "frreport_comm.h"
#include "frct_comm.h"

#include "../wtc_core.h"
#include "../wtc_comm.h"
#include "../wtc_mar.h"
#include "wtc_typed_fml32.h"
#include "wtc_typedbuffer.h"

FR_STATIC int __wtc_fld32no(int i_fldid32)
{
    return i_fldid32 & 0x1FFFFFF;
}

FR_STATIC int __wtc_fld32type(int i_fldid32)
{
    return i_fldid32 >> 25 & 0x3F;
}

FR_STATIC int __wtc_Fmbunpack32(Conntrack *p_st_conn
                                , L7session_wtc *p_st_sess
                                , unsigned int ui_fldid32
                                , char *p_field_name
                                , unsigned int ui_udlen
                                , char *p_value
                                , unsigned int ui_vallen
                                , Frreport_body_data *p_st_body)
{
    L7_session *p_st_session = frct_get_session(p_st_conn);
    L7session_wtc_private *p_st_session_private = (L7session_wtc_private *) frct_get_session_private(p_st_session);
    L7_wtc_stmt *p_st_wtc_stmt = p_st_session_private->p_st_wtc_stmt;
    L7_wtc_mbstring *p_st_wtc_mbstring = NULL;
    Frlist_node *p_st_node = NULL;
    Frbyte_Packet *buffer = NULL;
    char arr_magic[4] = {'\0'};
    char *p_mbencbytes = NULL;
    char *p_mbencoding = NULL;
    unsigned int ui_mbencoding_len = 0;
    char *p_udata = NULL;
    char *p_mbstring = NULL;
    unsigned int ui_mbstring_len = 0;

    if ((buffer = bytebuff_creat()) == NULL)
        return FR_FAIL;

    if (bytebuff_add(buffer, p_value, ui_vallen) != FR_SUCC)
        goto error;

    if (bytebuff_get_bytes(buffer, arr_magic, 4) != FR_SUCC)
        goto error;

    if ((arr_magic[3] & 0x1) == 0)
    {
        unsigned int mbenclen = ui_vallen - 4 - ui_udlen - 1;
        if ((p_mbencbytes = (char *) frmalloc(mbenclen * sizeof(char))) == NULL)
        {
            WTC_MALLOCK_ERR;
            goto error;
        }
        if (bytebuff_get_bytes(buffer, p_mbencbytes, mbenclen) != FR_SUCC)
            goto error;
        if (bytebuff_skip(buffer, 1) != FR_SUCC)
            goto error;
        if (wtc_mar_get_mbstring(p_st_sess->p_default_encoding, p_mbencbytes, mbenclen, &p_mbencoding, &ui_mbencoding_len) != FR_SUCC)
            goto error;
        WTC_PRINT_FATAL("p_mbencoding:[%s]\n", p_mbencoding);
        wtc_free((void **) &p_mbencbytes);
    }

    if ((p_udata = (char *) frmalloc(ui_udlen * sizeof(char))) == NULL)
    {
        WTC_MALLOCK_ERR;
        goto error;
    }
    if (bytebuff_get_bytes(buffer, p_udata, ui_udlen) != FR_SUCC)
        goto error;

    if (p_mbencoding != NULL)
    {
        if (wtc_mar_get_mbstring(p_mbencoding, p_udata, ui_udlen, &p_mbstring, &ui_mbstring_len) != FR_SUCC)
            goto error;
        wtc_free((void **) &p_udata);
        WTC_PRINT_ALERT("%s\n", p_mbstring);

        if (p_st_body != NULL)
        {
            if (frreport_body_l7_add_str(p_st_body, p_field_name, p_mbstring) != FR_SUCC)
                goto error;
            p_st_wtc_stmt->ui_arg_count++;
        }
        wtc_free((void **) &p_mbstring);
    }
    else
    {
        if ((p_st_wtc_mbstring = (L7_wtc_mbstring *) frmalloc(sizeof(L7_wtc_mbstring))) == NULL)
        {
            WTC_MALLOCK_ERR;
            goto error;
        }
        memset(p_st_wtc_mbstring, 0x00, sizeof(L7_wtc_mbstring));
        p_st_wtc_mbstring->ui_index = ui_fldid32;
        p_st_wtc_mbstring->p_mbstring = p_udata;
        p_st_wtc_mbstring->ui_mbstring_len = ui_udlen;
        p_st_node = frlist_node_create(p_st_wtc_mbstring);
        frlist_push(p_st_wtc_stmt->p_list_mbstring, p_st_node);
    }

    bytebuff_free(&buffer);
    wtc_free((void **) &p_mbencoding);
    return FR_SUCC;
error:
    bytebuff_free(&buffer);
    wtc_free((void **) &p_mbencbytes);
    wtc_free((void **) &p_mbencoding);
    wtc_free((void **) &p_mbstring);
    wtc_free((void **) &p_udata);
    return FR_FAIL;
}

int wtc_typed_fml32_tmpostrecv(Conntrack *p_st_conn
                            , L7session_wtc *p_st_sess
                            , L7_wtc_packet *p_st_wtc_packet
                            , int i_recv_size
                            , Frreport_body_data *p_st_body)
{
    WTC_PRINT_INFO("wtc_typed_fml32_tmpostrecv...\n");
    L7_session *p_st_session = frct_get_session(p_st_conn);
    L7session_wtc_private *p_st_session_private = (L7session_wtc_private *) frct_get_session_private(p_st_session);
    L7_wtc_stmt *p_st_wtc_stmt = p_st_session_private->p_st_wtc_stmt;
    unsigned int ui_magic = 0;
    unsigned int ui_mynfields = 0;
    unsigned int ui_lcv;
    unsigned int ui_lcv2;
    unsigned int ui_fldid32 = 0;
    int i_fldtype32 = 0;
    unsigned int ui_tmp = 0;
    float f_tmp = 0;
    double d_tmp = 0;
    unsigned int ui_fldlen = 0;
    unsigned int ui_udlen = 0;
    unsigned int ui_vallen = 0;
    int i_pad = 0;
    char *p_stringme = NULL;
    uint8_t byte;
    char *p_value_carray = NULL;
    char p_scratch[50] = {'\0'};
    char *p_type = NULL;
    unsigned int ui_type_len = 0;
    char *p_subtype = NULL;
    unsigned int ui_subtype_len = 0;
    typedbufferfunc f_typedbufferfunc = NULL;
    unsigned int ui_array_size = 0;
    char *p_value = NULL;
    char *p_str = NULL;
    unsigned int ui_str_len = 0;
    char *p_field_name = NULL;
    int i_field_name_len = 0;
    int i_position_in = bytebuff_getPosition(p_st_wtc_packet->p_st_packet);

    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_magic, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;

    if (bytebuff_skip(p_st_wtc_packet->p_st_packet, 8) != FR_SUCC)
        goto error;

    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_mynfields, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;

    if (bytebuff_skip(p_st_wtc_packet->p_st_packet, 8) != FR_SUCC)
        goto error;

    for (ui_lcv = 0; ui_lcv < ui_mynfields; ui_lcv++)
    {
        if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_fldid32, BYTE_BIG_ENDIAN) != FR_SUCC)
            goto error;
        if (__wtc_fld32no(ui_fldid32) == 0)
            goto error;
        i_fldtype32 = __wtc_fld32type((int) ui_fldid32);

        WTC_PRINT_FATAL("ui_fldid32:[%u] i_fldtype32:[%d]\n", ui_fldid32, i_fldtype32);
        i_field_name_len = strlen(p_st_wtc_packet->i_is_req == FR_YES ? APM_DTS_REPORT_REQ_ARG_DATA : APM_DTS_REPORT_RESP_ARG_DATA) + 16;
        if ((p_field_name = (char *) frmalloc(i_field_name_len * sizeof(char))) == NULL)
        {
            WTC_MALLOCK_ERR;
            goto error;
        }
        snprintf(p_field_name, (size_t) i_field_name_len, "%s%d", p_st_wtc_packet->i_is_req == FR_YES ? APM_DTS_REPORT_REQ_ARG_DATA
                                                                                                      : APM_DTS_REPORT_RESP_ARG_DATA, __wtc_fld32no(ui_fldid32));

        switch (i_fldtype32)
        {
            case APM_WTC_FLD_SHORT:
                if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                    goto error;
                WTC_PRINT_ALERT("short:[%d]\n", ui_tmp);
                if (p_st_body != NULL)
                {
                    if (frreport_body_l7_add_uint(p_st_body, p_field_name, ui_tmp) != FR_SUCC)
                        goto error;
                    p_st_wtc_stmt->ui_arg_count++;
                }
                break;
            case APM_WTC_FLD_LONG:
                if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                    goto error;
                WTC_PRINT_ALERT("int:[%d]\n", ui_tmp);
                if (p_st_body != NULL)
                {
                    if (frreport_body_l7_add_uint(p_st_body, p_field_name, ui_tmp) != FR_SUCC)
                        goto error;
                    p_st_wtc_stmt->ui_arg_count++;
                }
                break;
            case APM_WTC_FLD_CHAR:
                if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                    goto error;
                WTC_PRINT_ALERT("char:[%d]\n", ui_tmp);
                if (p_st_body != NULL)
                {
                    if (frreport_body_l7_add_uint(p_st_body, p_field_name, ui_tmp) != FR_SUCC)
                        goto error;
                    p_st_wtc_stmt->ui_arg_count++;
                }
                break;
            case APM_WTC_FLD_FLOAT:
                if (wtc_mar_get_float(p_st_wtc_packet, &f_tmp) != FR_SUCC)
                    goto error;
                WTC_PRINT_ALERT("float:[%f]\n", f_tmp);
                if (p_st_body != NULL)
                {
                    if (frreport_body_l7_add_float(p_st_body, p_field_name, f_tmp) != FR_SUCC)
                        goto error;
                    p_st_wtc_stmt->ui_arg_count++;
                }
                break;
            case APM_WTC_FLD_DOUBLE:
                if (wtc_mar_get_double(p_st_wtc_packet, &d_tmp) != FR_SUCC)
                    goto error;
                WTC_PRINT_ALERT("double:[%f]\n", d_tmp);
                if (p_st_body != NULL)
                {
                    if (frreport_body_l7_add_double(p_st_body, p_field_name, d_tmp) != FR_SUCC)
                        goto error;
                    p_st_wtc_stmt->ui_arg_count++;
                }
                break;
            case APM_WTC_FLD_STRING:
                if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_fldlen, BYTE_BIG_ENDIAN) != FR_SUCC)
                    goto error;
                ui_fldlen = ui_fldlen - 4 - 4;
                i_pad = wtc_mar_roundup4(ui_fldlen) - ui_fldlen;
                WTC_PRINT_FATAL("i_pad:[%d]\n", i_pad);
                if (bytebuff_skip(p_st_wtc_packet->p_st_packet, 4) != FR_SUCC)
                    goto error;
                if (ui_fldlen <= 1)
                {
                    if (bytebuff_skip(p_st_wtc_packet->p_st_packet, (size_t) (i_pad + 1)) != FR_SUCC)
                        goto error;
                    WTC_PRINT_ALERT("string:[]\n");
                    if (p_st_body != NULL)
                    {
                        if (frreport_body_l7_add_str(p_st_body, p_field_name, "") != FR_SUCC)
                            goto error;
                        p_st_wtc_stmt->ui_arg_count++;
                    }
                }
                else
                {
                    if ((p_stringme = (char *) frmalloc((ui_fldlen - 1) * sizeof(char))) == NULL)
                    {
                        WTC_MALLOCK_ERR;
                        goto error;
                    }
                    for (ui_lcv2 = 0; ui_lcv2 < ui_fldlen - 1; ui_lcv2++)
                    {
                        if (bytebuff_get_char(p_st_wtc_packet->p_st_packet, &byte) != FR_SUCC)
                            goto error;
                        p_stringme[ui_lcv2] = byte;
                    }
                    if (bytebuff_skip(p_st_wtc_packet->p_st_packet, (size_t) (i_pad + 1)) != FR_SUCC)
                        goto error;
                    if (wtc_mar_get_mbstring(p_st_sess->p_default_encoding, p_stringme, ui_fldlen - 1, &p_str, &ui_str_len) != FR_SUCC)
                        goto error;
                    WTC_PRINT_ALERT("string:[%s]\n", p_str);
                    if (p_st_body != NULL)
                    {
                        if (frreport_body_l7_add_str(p_st_body, p_field_name, p_str) != FR_SUCC)
                            goto error;
                        p_st_wtc_stmt->ui_arg_count++;
                    }
                    wtc_free((void **) &p_stringme);
                    wtc_free((void **) &p_str);
                }
                break;
            case APM_WTC_FLD_CARRAY:
                if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_fldlen, BYTE_BIG_ENDIAN) != FR_SUCC)
                    goto error;
                ui_fldlen = ui_fldlen - 4 - 4;
                i_pad = wtc_mar_roundup4(ui_fldlen) - ui_fldlen;
                WTC_PRINT_FATAL("i_pad:[%d]\n", i_pad);
                if (bytebuff_skip(p_st_wtc_packet->p_st_packet, 4) != FR_SUCC)
                    goto error;
                if (ui_fldlen == 0)
                {
                    p_value_carray = NULL;
                    ui_fldlen = 0;
                }
                else
                {
                    if ((p_value_carray = (char *) frmalloc(ui_fldlen * sizeof(char))) == NULL)
                    {
                        WTC_MALLOCK_ERR;
                        goto error;
                    }
                    for (ui_lcv2 = 0; ui_lcv2 < ui_fldlen; ui_lcv2++)
                    {
                        if (bytebuff_get_char(p_st_wtc_packet->p_st_packet, &byte) != FR_SUCC)
                            goto error;
                        p_value_carray[ui_lcv2] = byte;
                    }
                    if (bytebuff_skip(p_st_wtc_packet->p_st_packet, (size_t) i_pad) != FR_SUCC)
                        goto error;
                }
                WTC_PRINT_ALERT("carray:[CARRAY]\n");
                if (p_st_body != NULL)
                {
                    if (frreport_body_l7_add_bin(p_st_body, p_field_name, p_value_carray, ui_fldlen) != FR_SUCC)
                        goto error;
                    p_st_wtc_stmt->ui_arg_count++;
                }
                wtc_free((void **) &p_value_carray);
                break;
            case APM_WTC_FLD_PTR:
                if (wtc_mar_decode_string(p_st_sess, p_scratch, 50, p_st_wtc_packet, &p_type, &ui_type_len) != FR_SUCC)
                    goto error;
                WTC_PRINT_FATAL("p_type:[%s]\n", p_type);

                if (wtc_mar_decode_string(p_st_sess, p_scratch, 50, p_st_wtc_packet, &p_subtype, &ui_subtype_len) != FR_SUCC)
                    goto error;
                WTC_PRINT_FATAL("p_subtype:[%s]\n", p_subtype);

                if (p_type == NULL)
                {
                    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                        goto error;
                    if (ui_tmp != 0)
                        goto error;
                    if (p_st_body != NULL)
                    {
                        if (frreport_body_l7_add_str(p_st_body, p_field_name, "") != FR_SUCC)
                            goto error;
                        p_st_wtc_stmt->ui_arg_count++;
                    }
                }
                else
                {
                    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_array_size, BYTE_BIG_ENDIAN) != FR_SUCC)
                        goto error;
                    if (ui_array_size == 0)
                    {
                        if (p_st_body != NULL)
                        {
                            if (frreport_body_l7_add_str(p_st_body, p_field_name, "") != FR_SUCC)
                                goto error;
                            p_st_wtc_stmt->ui_arg_count++;
                        }
                    }
                    else
                    {
                        if ((f_typedbufferfunc = wtc_create_typedbuffer_by_type(p_type, p_subtype)) == NULL)
                        {
                            if (wtc_add_typedbuffer(p_st_conn, p_type, p_subtype, ui_fldid32, p_st_wtc_packet, ui_array_size,
                                                    p_st_body) != FR_SUCC)
                                goto error;
                        }
                        else
                        {
                            if (f_typedbufferfunc(p_st_conn, p_st_sess, p_st_wtc_packet, i_recv_size, p_st_body) != FR_SUCC)
                                goto error;
                        }
                        i_pad = wtc_mar_roundup4(ui_array_size) - ui_array_size;
                        if (bytebuff_skip(p_st_wtc_packet->p_st_packet, (size_t) i_pad) != FR_SUCC)
                            goto error;
                    }
                }
                wtc_free((void **) &p_type);
                wtc_free((void **) &p_subtype);
                break;
            case APM_WTC_FLD_FML32:
                if (wtc_typed_fml32_tmpostrecv(p_st_conn, p_st_sess, p_st_wtc_packet, 0, p_st_body) != FR_SUCC)
                    goto error;
                break;
            case APM_WTC_FLD_MBSTRING:
                if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_fldlen, BYTE_BIG_ENDIAN) != FR_SUCC)
                    goto error;
                if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_udlen, BYTE_BIG_ENDIAN) != FR_SUCC)
                    goto error;
                if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_vallen, BYTE_BIG_ENDIAN) != FR_SUCC)
                    goto error;
//                WTC_PRINT_EMERG("ui_fldlen:[%u] ui_udlen:[%u] ui_vallen:[%u]\n", ui_fldlen, ui_udlen, ui_vallen);
                if (ui_vallen == 0)
                {
                    if (p_st_body != NULL)
                    {
                        if (frreport_body_l7_add_str(p_st_body, p_field_name, "") != FR_SUCC)
                            goto error;
                        p_st_wtc_stmt->ui_arg_count++;
                    }
                }
                else
                {
                    if ((p_value = (char *) frmalloc(ui_vallen * sizeof(char))) == NULL)
                    {
                        WTC_MALLOCK_ERR;
                        goto error;
                    }
                    for (ui_lcv2 = 0; ui_lcv2 < ui_vallen; ui_lcv2++)
                    {
                        if (bytebuff_get_char(p_st_wtc_packet->p_st_packet, &byte) != FR_SUCC)
                            goto error;
                        p_value[ui_lcv2] = byte;
                    }
                    PRINT_HEX_STRING("fml32 mbstring", p_value, ui_vallen);
                    if (__wtc_Fmbunpack32(p_st_conn, p_st_sess, ui_fldid32, p_field_name, ui_udlen, p_value, ui_vallen, p_st_body) != FR_SUCC)
                        goto error;
                    wtc_free((void **) &p_value);
                    i_pad = wtc_mar_roundup4(ui_fldlen) - ui_fldlen;
                    if (bytebuff_skip(p_st_wtc_packet->p_st_packet, (size_t) i_pad) != FR_SUCC)
                        goto error;
                }
                break;
            case APM_WTC_FLD_VIEW32:
                if (wtc_mar_decode_string(p_st_sess, p_scratch, 50, p_st_wtc_packet, &p_subtype, &ui_subtype_len) != FR_SUCC)
                    goto error;
                WTC_PRINT_FATAL("p_subtype:[%s]\n", p_subtype);
                // XXX: 这里不能确定fml32包含view32时的编码情况，所以不知道什么时候结束，故剩余的参数全部跳过
                if (bytebuff_setPosition(p_st_wtc_packet->p_st_packet, i_recv_size + i_position_in) != FR_SUCC)
                    goto error;
                wtc_free((void **) &p_field_name);
                goto success;
//                if ((f_typedbufferfunc = wtc_create_typedbuffer_by_type((char *) APM_WTC_VIEW32_STRING, p_subtype)) != NULL)
//                {
//                    if (f_typedbufferfunc(p_st_conn, p_st_sess, p_st_wtc_packet, 0, NULL) != FR_SUCC)
//                        goto error;
//                }
//                if (wtc_add_typedbuffer(p_st_conn, (char *) APM_WTC_VIEW32_STRING, p_subtype, ui_fldid32,
//                                        p_st_wtc_packet, p_st_body) != FR_SUCC)
//                    goto error;
            case APM_WTC_FLD_INT:
            case APM_WTC_FLD_DECIMAL:
            default:
                goto error;
        }

        wtc_free((void **) &p_field_name);
    }

success:
    wtc_free((void **) &p_stringme);
    wtc_free((void **) &p_value_carray);
    wtc_free((void **) &p_type);
    wtc_free((void **) &p_subtype);
    wtc_free((void **) &p_value);
    return FR_SUCC;
error:
    wtc_free((void **) &p_field_name);
    wtc_free((void **) &p_stringme);
    wtc_free((void **) &p_value_carray);
    wtc_free((void **) &p_type);
    wtc_free((void **) &p_subtype);
    wtc_free((void **) &p_value);
    return FR_FAIL;
}


//////////////////////// for analyze direction
int wtc_typed_fml32_tmpostrecv_fad(int i_recv_size
                                , char *p_payload
                                , unsigned int ui_payload_len
                                , unsigned int *p_ui_offset)
{
    WTC_PRINT_INFO("wtc_typed_fml32_tmpostrecv_fad...\n");
    unsigned int ui_mynfields = 0;
    unsigned int ui_lcv;
    unsigned int ui_fldid32 = 0;
    int i_fldtype32 = 0;
    unsigned int ui_tmp = 0;
    unsigned int ui_fldlen = 0;
    unsigned int ui_udlen = 0;
    unsigned int ui_vallen = 0;
    int i_pad = 0;
    char p_scratch[50] = {'\0'};
    char *p_type = NULL;
    unsigned int ui_type_len = 0;
    char *p_subtype = NULL;
    unsigned int ui_subtype_len = 0;
    typedbufferfunc_fad f_typedbufferfunc_fad = NULL;
    unsigned int ui_array_size = 0;

    if (wtc_skip_int(p_payload, ui_payload_len, p_ui_offset) != FR_SUCC) // ui_magic
        goto error;

    if (wtc_skip(p_payload, ui_payload_len, p_ui_offset, 8) != FR_SUCC)
        goto error;

    if (wtc_get_int(p_payload, ui_payload_len, p_ui_offset, &ui_mynfields) != FR_SUCC)
        goto error;

    if (wtc_skip(p_payload, ui_payload_len, p_ui_offset, 8) != FR_SUCC)
        goto error;

    for (ui_lcv = 0; ui_lcv < ui_mynfields; ui_lcv++)
    {
        if (wtc_get_int(p_payload, ui_payload_len, p_ui_offset, &ui_fldid32) != FR_SUCC)
            goto error;
        if (__wtc_fld32no(ui_fldid32) == 0)
            goto error;
        i_fldtype32 = __wtc_fld32type((int) ui_fldid32);

//        WTC_PRINT_FATAL("ui_fldid32:[%u] i_fldtype32:[%d]\n", ui_fldid32, i_fldtype32);
        switch (i_fldtype32)
        {
            case APM_WTC_FLD_SHORT:
            case APM_WTC_FLD_LONG:
            case APM_WTC_FLD_CHAR:
                if (wtc_skip_int(p_payload, ui_payload_len, p_ui_offset) != FR_SUCC)
                    goto error;
                break;
            case APM_WTC_FLD_FLOAT:
                if (wtc_skip_float(p_payload, ui_payload_len, p_ui_offset) != FR_SUCC)
                    goto error;
                break;
            case APM_WTC_FLD_DOUBLE:
                if (wtc_skip_double(p_payload, ui_payload_len, p_ui_offset) != FR_SUCC)
                    goto error;
                break;
            case APM_WTC_FLD_STRING:
                if (wtc_get_int(p_payload, ui_payload_len, p_ui_offset, &ui_fldlen) != FR_SUCC)
                    goto error;
                ui_fldlen = ui_fldlen - 4 - 4;
                i_pad = wtc_mar_roundup4(ui_fldlen) - ui_fldlen;
                if (wtc_skip(p_payload, ui_payload_len, p_ui_offset, 4) != FR_SUCC)
                    goto error;
                if (ui_fldlen <= 1)
                {
                    if (wtc_skip(p_payload, ui_payload_len, p_ui_offset, i_pad + 1) != FR_SUCC)
                        goto error;
                }
                else
                {
                    if (wtc_skip(p_payload, ui_payload_len, p_ui_offset, ui_fldlen - 1) != FR_SUCC)
                        goto error;
                    if (wtc_skip(p_payload, ui_payload_len, p_ui_offset, i_pad + 1) != FR_SUCC)
                        goto error;
                }
                break;
            case APM_WTC_FLD_CARRAY:
                if (wtc_get_int(p_payload, ui_payload_len, p_ui_offset, &ui_fldlen) != FR_SUCC)
                    goto error;
                ui_fldlen = ui_fldlen - 4 - 4;
                i_pad = wtc_mar_roundup4(ui_fldlen) - ui_fldlen;
                if (wtc_skip(p_payload, ui_payload_len, p_ui_offset, 4) != FR_SUCC)
                    goto error;
                if (ui_fldlen != 0)
                {
                    if (wtc_skip(p_payload, ui_payload_len, p_ui_offset, ui_fldlen) != FR_SUCC)
                        goto error;
                    if (wtc_skip(p_payload, ui_payload_len, p_ui_offset, i_pad) != FR_SUCC)
                        goto error;
                }
                break;
            case APM_WTC_FLD_PTR:
                if (wtc_mar_decode_string_fad(p_payload, ui_payload_len, p_ui_offset, p_scratch, 50, &p_type, &ui_type_len) != FR_SUCC)
                    goto error;
                WTC_PRINT_FATAL("p_type:[%s]\n", p_type);

                if (wtc_mar_decode_string_fad(p_payload, ui_payload_len, p_ui_offset, p_scratch, 50, &p_subtype, &ui_subtype_len) != FR_SUCC)
                    goto error;
                WTC_PRINT_FATAL("p_subtype:[%s]\n", p_subtype);

                if (p_type == NULL)
                {
                    if (wtc_get_int(p_payload, ui_payload_len, p_ui_offset, &ui_tmp) != FR_SUCC)
                        goto error;
                    if (ui_tmp != 0)
                        goto error;
                }
                else
                {
                    if (wtc_get_int(p_payload, ui_payload_len, p_ui_offset, &ui_array_size) != FR_SUCC)
                        goto error;
                    if (ui_array_size != 0)
                    {
                        if ((f_typedbufferfunc_fad = wtc_create_typedbuffer_by_type_fad(p_type, p_subtype)) == NULL)
                        {
                            if (wtc_skip(p_payload, ui_payload_len, p_ui_offset, ui_array_size) != FR_SUCC)
                                goto error;
                        }
                        else
                        {
                            if (f_typedbufferfunc_fad(i_recv_size, p_payload, ui_payload_len, p_ui_offset) != FR_SUCC)
                                goto error;
                        }
                        i_pad = wtc_mar_roundup4(ui_array_size) - ui_array_size;
                        if (wtc_skip(p_payload, ui_payload_len, p_ui_offset, i_pad) != FR_SUCC)
                            goto error;
                    }
                }
                wtc_free((void **) &p_type);
                wtc_free((void **) &p_subtype);
                break;
            case APM_WTC_FLD_FML32:
                if (wtc_typed_fml32_tmpostrecv_fad(0, p_payload, ui_payload_len, p_ui_offset) != FR_SUCC)
                    goto error;
                break;
            case APM_WTC_FLD_MBSTRING:
                if (wtc_get_int(p_payload, ui_payload_len, p_ui_offset, &ui_fldlen) != FR_SUCC)
                    goto error;
                if (wtc_get_int(p_payload, ui_payload_len, p_ui_offset, &ui_udlen) != FR_SUCC)
                    goto error;
                if (wtc_get_int(p_payload, ui_payload_len, p_ui_offset, &ui_vallen) != FR_SUCC)
                    goto error;
                WTC_PRINT_EMERG("ui_fldlen:[%u] ui_udlen:[%u] ui_vallen:[%u]\n", ui_fldlen, ui_udlen, ui_vallen);
                if (ui_vallen != 0)
                {
                    if (wtc_skip(p_payload, ui_payload_len, p_ui_offset, ui_vallen) != FR_SUCC)
                        goto error;
                    i_pad = wtc_mar_roundup4(ui_fldlen) - ui_fldlen;
                    if (wtc_skip(p_payload, ui_payload_len, p_ui_offset, i_pad) != FR_SUCC)
                        goto error;
                }
                break;
            case APM_WTC_FLD_VIEW32: // 这里不能确定fml32包含view32时的编码情况，所以不知道什么时候结束，所以当作失败处理
            case APM_WTC_FLD_INT:
            case APM_WTC_FLD_DECIMAL:
            default:
                goto error;
        }
    }

    wtc_free((void **) &p_type);
    wtc_free((void **) &p_subtype);
    return FR_SUCC;
error:
    wtc_free((void **) &p_type);
    wtc_free((void **) &p_subtype);
    return FR_FAIL;
}
